home *** CD-ROM | disk | FTP | other *** search
/ The Atari Compendium / The Atari Compendium (Toad Computers) (1994).iso / files / prgtools / mint / mint108s.zoo / intr.spp < prev    next >
Encoding:
Text File  |  1993-07-27  |  13.2 KB  |  519 lines

  1. ; Copyright 1992 Eric R. Smith
  2. ; All rights reserved.
  3.  
  4. %include "magic.i"
  5. ;
  6. ; interrupt wrapping routines; these should just save registers and call
  7. ; the appropriate C handlers, unless speed is a major problem
  8. ;
  9.     TEXT
  10. ;
  11. ; first, utilities for setting processor status level
  12. ;
  13.     XDEF    _spl7,_spl
  14. _spl7:
  15.     move.w    sr,d0
  16.     ori.w    #$0700,sr
  17.     rts
  18. _spl:
  19.     move.w    4(sp),sr
  20.     rts
  21.  
  22.     XDEF    _mint_5ms
  23.     XDEF    _mint_timer
  24.     XDEF    _mint_vbl
  25.     XREF    _timeout    ; C time routine
  26.     XREF    _old_timer    ; old GEMDOS time vector
  27.     XREF    _old_vbl    ; old GEMDOS vbl vector
  28.     XREF    _old_5ms
  29.     XREF    _build_context
  30.     XREF    _restore_context
  31.     XREF    _proc_clock        ; controls process' allocation of CPU time
  32.     XREF    _curproc
  33.     XREF    _enter_kernel
  34.     XREF    _leave_kernel
  35.     XREF    _preempt
  36.     XREF    _in_kernel
  37.  
  38. ; AKP: this code is hit once every 5ms; it updates the time fields of curproc.
  39. _mint_5ms:
  40.     move.l    a0,-(sp)
  41.     move.l    _curproc,a0
  42.     tst.w    _in_kernel
  43.     bne.s    L_systime
  44.     lea    P_USRTIME(a0),a0    ; get offset to curproc->usrtime
  45.     addq.l    #5,(a0)            ; update the time
  46.     move.l    (sp)+,a0
  47.     move.l    _old_5ms+8,-(sp)    ; branch to old vector
  48.     rts
  49. L_systime:
  50.     lea    P_SYSTIME(a0),a0    ; get offset to curproc->systime
  51.     addq.l    #5,(a0)
  52.     move.l    (sp)+,a0
  53.     move.l    _old_5ms+8,-(sp)
  54.     rts
  55.  
  56. _mint_timer:
  57.     movem.l    d0-d2/a0-a2,-(sp)    ; save C registers
  58.     jsr    _timeout
  59.     movem.l    (sp)+,d0-d2/a0-a2
  60.     move.l    _old_timer+8,-(sp)    ; jump to GEMDOS time vector
  61.     rts
  62.  
  63. _mint_vbl:
  64. %ifndef ONLY030
  65.     tst.w    ($59e).w        ; test longframe (AKP)
  66.     beq.s    L_short1
  67. %endif
  68.     clr.w    -(sp)            ; yes, long frames: push a frame word
  69. L_short1:
  70.     pea    L_comeback        ; push fake PC
  71.     move.w    sr,-(sp)        ; push status register
  72.     move.l    _old_vbl+8,-(sp)    ; go service the interrupt
  73.     rts
  74.  
  75. L_comeback:
  76.     tst.w    _proc_clock        ; has time expired yet?
  77.     beq.s    L_expired        ; yes -- maybe go switch processes
  78. L_out:
  79.     rte                ; no -- just return
  80.  
  81. L_expired:
  82.     btst    #5,(sp)            ; user mode?
  83.     bne.s    L_out            ; no -- switching is not possible
  84.     tst.w    ($43e).w        ; test floppy disk lock variable
  85.     bne.s    L_out            ; if locked, can't switch
  86.     tst.w    _in_kernel        ; are we doing a kernel operation?
  87.     bne.s    L_out
  88. L_switch:
  89.     clr.w    -(sp)            ; no frame format needed
  90.     move.l    _curproc,-(sp)
  91.     addq.l    #P_CTXT0,(sp)            ; to get &curproc->ctxt[SYSCALL]
  92.     jsr    _build_context        ; build context
  93.     move.l    _curproc,a0
  94.     move.l    (a0),sp            ; use curproc->sysstack
  95.     jsr    _enter_kernel        ; enter kernel
  96.     jsr    _preempt        ; yield processor
  97.     ori.w    #$700,sr        ; spl7()
  98.     jsr    _leave_kernel        ; restore vectors
  99.     move.l    _curproc,a0
  100.     pea    4(a0)
  101.     jsr    _restore_context    ; back to user
  102.  
  103. ;
  104. ; reset routine -- called on a warm boot. Note that TOS sends the
  105. ; address to which we should return in register a6. Also note that
  106. ; the stack pointer is in an unknown state, so we set up our own
  107. ;
  108.     XDEF    _reset
  109.     XREF    _init_tail        ; see main.c
  110.     XREF    _restr_intr
  111.  
  112. _reset:
  113.     move.w    #$2700,sr        ; avoid interruption here
  114.     move.l    sp,_init_tail        ; save A7
  115.     lea    _init_tail,sp        ; set up temporary stack
  116.     lea    256(sp),sp
  117.     movem.l    d0-d2/a0-a2,-(sp)    ; save C registers
  118.     jsr    _restr_intr        ; restore interrupts
  119.     movem.l    (sp)+,d0-d2/a0-a2    ; restore registers
  120.     move.l    _init_tail,sp
  121.     jmp    (a6)            ; reset again
  122.  
  123. ;
  124. ; routine for doing a reboot
  125. ;
  126.     XDEF    _reboot
  127. _reboot:
  128.     move.w    #$2700,sr        ; avoid interrupts
  129.     move.l    (0).w,sp        ; get sp after reboot
  130.     move.l    (4).w,a6        ; get new reboot address
  131.     jmp    _reset
  132.  
  133. ;
  134. ; routine for mouse packet handling
  135. ;
  136.     XDEF    _newmvec
  137.     XDEF    _newjvec
  138.     XREF    _mouse_handler
  139. ; Experimental three button mouse support (by jr@ms.maus.de,
  140. ; August 4, 1992
  141. ;
  142. ; Should work with the mice shipped with Atari's ASV or
  143. ; compatible ones (like Golden Image GI-6000). Might not work
  144. ; on ST/STE systems with older IKBD's or keyboards. The middle mouse
  145. ; button is wired to one of the joystick directions on joystick one.
  146. ;
  147. ; _newmvec is the same as before with two exceptions:
  148. ; 1. the first byte of the packet is saved for the joystick handler
  149. ; 2. the bit for the middle mouse button is ored in
  150. ;
  151. ; _newjvec hooks into the joystick vector and chains to the normal
  152. ; handler. The middle mouse button state is saved in a special
  153. ; register for _newmvec, and a 'fake' mouse packet is set up
  154. ; (by merging the last mouse packet header, or-ing in the
  155. ; middle button state and using 0/0 for the x/y increment).
  156. ;
  157. ; the faked_packet and third_button variables are declared at the
  158. ; end of this file
  159.  
  160. _newmvec:
  161.     move.l    a0,-(sp)
  162.     move.b    (a0),d0
  163.     move.b    d0,faked_packet
  164.     or.b    third_button,d0
  165.     move.b    d0,(a0)
  166.     jsr    _mouse_handler
  167.     move.l    (sp)+,a0
  168.     rts
  169. ;
  170. ; routine for joystick packet handling (used for three button mice)
  171. ;
  172.     XDEF    _newjvec
  173.     XREF    _oldjvec
  174.  
  175. _newjvec:
  176.     move.l    a0,-(sp)    ; save a0 on the stack
  177.     move.b    2(a0),d0    ; joystick direction
  178.     and.b    #1,d0        ; middle mouse button in lowest bit
  179.     add.b    d0,d0        ; times 4
  180.     add.b    d0,d0
  181.     move.b    d0,third_button    ; save it for use in newmvec
  182.  
  183.     lea    faked_packet,a0    ; 'our' faked mouse event
  184.     move.b    (a0),d0
  185.     and.b    #$3,d0        ; unmask our mouse button
  186.     or.b    #$F8,d0        ; or in correct header
  187.     or.b    third_button,d0    ; or in the current status
  188.     move.b    d0,(a0)        ; write it back
  189.  
  190.     move.l    a0,-(sp)    ; pass pointer to fake packet
  191.     jsr    _mouse_handler    ; to \dev\mouse handler
  192.     addq.l    #4,sp        ; pop parameter
  193.     move.l    (sp)+,a0    ; restore original a0 value
  194.     move.l    _oldjvec,-(sp)    ; jump to original joystick handler
  195.     rts
  196. ;
  197. ; new ikbd keyboard interrupt vector
  198. ; kintr is a global variable that should be non-zero if a keyboard
  199. ; event occured
  200. ;
  201.     XDEF    _new_ikbd
  202.     XREF    _old_ikbd
  203.     XREF    _kintr
  204.  
  205. _new_ikbd:
  206.     move.w    #1,_kintr
  207.     move.l    _old_ikbd+8,-(sp)
  208.     rts            ; jump to system interrupt routine
  209.  
  210. ;
  211. ; simple signal handlers
  212. ; global variables referenced:
  213. ; in_kernel: (main.c): flag to indicate that we're in the MiNT kernel
  214. ; sig_routine: (signal.c): pointer to which signal catching routine to
  215. ;          call (e.g. for SIGBUS, or whatever)
  216. ;
  217.     XDEF    _new_bus,_new_addr,_new_ill,_new_divzero,_new_priv,_new_linef
  218.     XDEF    _new_trace,_new_chk,_new_trapv,_new_fpcp,_new_mmu,_new_pmmuacc
  219.     XDEF    _new_uninit,_new_spurious,_new_format,_new_cpv
  220.     XREF    _in_kernel,_sig_routine
  221.     XREF    _sigbus,_sigaddr,_sigill,_sigfpe,_sigpriv,_sigtrap
  222.     XREF    _haltformat,_haltcpv
  223.     XREF    _sig_exc
  224.     XREF    _mcpu
  225.     
  226. ;
  227. ; New bus error handler for memory protection: get the ssp and
  228. ; put it in the proc structure before calling
  229. ; _sigbus.  When the bus error happens in the kernel we don't save
  230. ; any contexts.
  231. ; We don't want to mess up any registers here because we might bring the
  232. ; page in and RTE.
  233. ;
  234.  
  235. _new_bus:
  236. %ifndef ONLY030
  237.     move.w    #$8,_sig_exc
  238.     cmp.l    #30,_mcpu
  239.     bne.s    noMMU
  240. %endif
  241.     move.l    #_mmu_sigbus,_sig_routine
  242. %ifndef ONLY030
  243.     bra.s    Do_sig
  244. noMMU:
  245.     move.l    #_nommu_sigbus,_sig_routine
  246. %endif
  247. Do_sig:
  248.     move.l    a0,-(sp)        ; save a0
  249.     move.l    _curproc,a0
  250.     move.l    sp,P_EXCSSP(a0)
  251.     addq.l    #4,P_EXCSSP(a0)
  252.     move.l    6(sp),P_EXCPC(a0)
  253.     move.l    (sp)+,a0
  254.  
  255.     tst.w    _in_kernel        ; are we already in the kernel?
  256.     bne.s    Kernel            ; yes
  257.     move.w    _sig_exc,-(sp)
  258.     move.l    _curproc,-(sp)
  259.     addq.l    #4,(sp)            ; push offset of save area
  260.     jsr    _build_context
  261.     move.l    _curproc,a4
  262.     move.l    (a4),sp            ; put us in the system stack
  263.     jsr    _enter_kernel        ; set up kernel vectors
  264.     move.l    _sig_routine,a1        ; get signal handling routine
  265.     jsr    (a1)            ; go do it
  266.     ori.w    #$0700,sr        ; spl7()
  267.     jsr    _leave_kernel        ; leave kernel
  268.     addq.w    #4,a4            ; get context save area address
  269.     move.l    a4,-(sp)        ; push it
  270.     jsr    _restore_context    ; restore the context
  271. ;
  272. ; here's what we do if we already were in the kernel
  273. ;
  274. Kernel:
  275.     movem.l    d0-d2/a0-a2,-(sp)    ; save reggies
  276.     move.l    _sig_routine,a1        ; get handler
  277.     jsr    (a1)            ; go do it
  278.     movem.l    (sp)+,d0-d2/a0-a2
  279.     rte
  280.  
  281. ;
  282. ; _mmu_sigbus: a pre-handler for _sigbus.  Check the reason for the bus
  283. ; error and report if it was a real access fault.
  284. ;
  285. _mmu_sigbus:
  286.     move.l    a2,-(sp)
  287.     move.l    _curproc,a0
  288.     move.l    P_EXCSSP(a0),a1        ; a1 is now exception_ssp
  289.     move.w    $A(a1),d0        ; d0 is SSR
  290.     move.l    $10(a1),a1        ; a1 is the access address
  291.     move.l    a1,P_EXCADDR(a0)    ; save the access address
  292.  
  293.     ptestr    d0,(a1),#7,a2        ; a2 is the table address
  294.     move.l    a2,P_EXCTBL(a0)        ; save table address in curproc
  295.     pmove    mmusr,P_EXCMMUSR(a0)    ; save resulting mmusr in curproc
  296.     move.l    (sp)+,a2
  297.     jmp    _sigbus        ; chain to bus-error handler
  298. %ifndef ONLY030
  299. ;
  300. ; _nommu_sigbus: handler for bus errors on machines without MMU
  301.  
  302. _nommu_sigbus:
  303.     move.l    _curproc,a0
  304.     move.l    P_EXCSSP(a0),a1
  305.     lea    $10(a1),a1        ; point to access address
  306.     tst.w    ($59e).w        ; test longframe
  307.     beq.s    NOMMU1
  308.     addq.w    #8,a1            ; on 68000, address is 8 bytes further
  309. NOMMU1:
  310.     move.l    (a1),P_EXCADDR(a0)    ; save the access address
  311.     jmp    _sigbus
  312. %endif
  313.  
  314. _new_addr:
  315. %ifndef ONLY030
  316.     move.w    #$c,_sig_exc
  317. %endif
  318.     move.l    #_sigaddr,_sig_routine
  319.     bra    Do_sig
  320. _new_ill:
  321. %ifndef ONLY030
  322.     move.w    #$10,_sig_exc
  323. %endif
  324.     move.l    #_sigill,_sig_routine
  325.     bra    Do_sig
  326. _new_divzero:
  327. %ifndef ONLY030
  328.     move.w    #$14,_sig_exc
  329. %endif
  330.     move.l    #_sigfpe,_sig_routine
  331.     bra    Do_sig
  332. _new_linef:
  333. %ifndef ONLY030
  334.     move.w    #$2c,_sig_exc
  335. %endif
  336.     move.l    #_sigill,_sig_routine
  337.     bra    Do_sig
  338. _new_chk:
  339. %ifndef ONLY030
  340.     move.w    #$18,_sig_exc
  341. %endif
  342.     move.l    #_sigfpe,_sig_routine
  343.     bra    Do_sig
  344. _new_trapv:
  345. %ifndef ONLY030
  346.     move.w    #$1c,_sig_exc
  347. %endif
  348.     move.l    #_sigfpe,_sig_routine
  349.     bra    Do_sig
  350. _new_fpcp:
  351. ; don't set _sig_exc - only needed for 68000 vectors
  352.     move.l    #_sigfpe,_sig_routine
  353.     bra    Do_sig
  354. _new_mmu:
  355. ; don't set _sig_exc - only needed for 68000 vectors
  356.     move.l    #_sigill,_sig_routine
  357.     bra    Do_sig
  358. _new_pmmuacc:
  359. ; don't set _sig_exc - only needed for 68000 vectors
  360.     move.l    #_sigbus,_sig_routine
  361.     bra    Do_sig
  362. _new_uninit:
  363. %ifndef ONLY030
  364.     move.w    #$3c,_sig_exc
  365. %endif
  366.     move.l    #_sigbus,_sig_routine
  367.     bra    Do_sig
  368. _new_spurious:
  369. %ifndef ONLY030
  370.     move.w    #$60,_sig_exc
  371. %endif
  372.     move.l    #_sigbus,_sig_routine
  373.     bra    Do_sig
  374. _new_format:
  375.     move.l    #_haltformat,_sig_routine
  376.     bra    Do_sig
  377. _new_cpv:
  378.     move.l    #_haltcpv,_sig_routine
  379.     bra    Do_sig
  380.  
  381.     XREF    _old_priv        ; old privilege violation vector
  382. _new_priv:
  383. %ifndef ONLY030
  384.     move.w    #$20,_sig_exc
  385. %endif
  386.     move.l    #_sigpriv,_sig_routine
  387. %ifndef ONLY030
  388.     tst.w    ($59e).w        ; 68000s always get SIGPRIV
  389.     beq    Do_sig
  390. %endif
  391.     movem.l    d0/a0,-(a7)
  392.     move.l    10(a7),a0        ; fetch exception address
  393.     move.w    (a0),d0
  394.     and.w    #$ffc0,d0        ; partially decode move sr,...
  395.     cmp.w    #$40c0,d0        ; and test it
  396.     movem.l    (a7)+,d0/a0        ; preserves the flags
  397.     bne    Do_sig            ; doesn't look like sr,...
  398.     move.l    _old_priv+8,-(sp)    ; let our parent handle it
  399.     rts
  400.  
  401. ; XBRA vectors from main.c
  402.     XREF    _old_dos,_old_bios,_old_xbios
  403.     XREF    _old_divzero,_old_chk,_old_trapv
  404.  
  405. _new_trace:
  406.     btst    #5,(a7)            ; only check when called from supervisor mode
  407.     beq.s    S_1
  408.     cmp.l    #_old_dos+12,2(a7)    ; lets not trace the kernel !
  409.     beq.s    S_2
  410.     cmp.l    #_old_xbios+12,2(a7)
  411.     beq.s    S_2
  412.     cmp.l    #_old_bios+12,2(a7)
  413.     beq.s    S_2
  414.     cmp.l    #_old_divzero+12,2(a7)
  415.     beq.s    S_2
  416.     cmp.l    #_old_trapv+12,2(a7)
  417.     beq.s    S_2
  418.     cmp.l    #_old_chk+12,2(a7)
  419.     beq.s    S_2
  420. ; add any other non-traceable entities here...
  421.  
  422. S_1:    move.w    #$24,_sig_exc
  423.     move.l    #_sigtrap,_sig_routine
  424.     bra    Do_sig
  425.  
  426. S_2:    and.w    #$3fff,(a7)        ; clear both trace bits
  427.     rte                ; and re-start the handler
  428.  
  429. ;
  430. ; BIOS disk vectors for pseudo-disks like U: and X:; these are present
  431. ; just in case some program (foolishly) attempts to access these drives
  432. ; directly and gets horribly confused
  433. ;
  434.     XREF    _old_getbpb    ; old Getbpb vector
  435.     XREF    _old_mediach    ; old Mediach vector
  436.     XREF    _old_rwabs    ; old Rwabs vector
  437.     XREF    _aliasdrv    ; array of drive aliases
  438.     XDEF    _new_getbpb
  439.     XDEF    _new_mediach
  440.     XDEF    _new_rwabs
  441.  
  442. _new_getbpb:
  443.     move.w    4(sp),d0    ; check the drive
  444.     cmp.w    #$1f,d0        ; legal drive?
  445.     bhi.s    noalias0    ; no
  446.     move.w    d0,d1        ; get index
  447.     add.w    d0,d1        ; convert to index
  448.     lea    _aliasdrv,a0
  449.     move.w    0(a0,d1.w),d1    ; alias drive?
  450.     beq.s    noalias0
  451.     move.w    d1,d0
  452.     subq.w    #1,d0        ; adjust for aliasdrv base of '@'
  453.     cmp.w    #$1f,d0        ; is this a legal drive?
  454.     bhi.s    nobpb        ; no -- ignore it
  455. noalias0:
  456.     cmp.w    #$14,d0        ; drive U:?
  457.     beq.s    nobpb        ; yes, no BPB available
  458.     move.l    _old_getbpb+8,a0    ; not our drive
  459.     jmp    (a0)        ; call the old vector for it
  460. nobpb:
  461.     moveq.l    #0,d0        ; 0 means "no BPB read"
  462.     rts
  463.  
  464. _new_mediach:
  465.     move.w    4(sp),d0    ; check the drive
  466.     cmp.w    #$1f,d0        ; legal drive?
  467.     bhi.s    noalias1    ; no
  468.     move.w    d0,d1        ; get index
  469.     add.w    d0,d1        ; convert to index
  470.     lea    _aliasdrv,a0
  471.     move.w    0(a0,d1.w),d1    ; alias drive?
  472.     beq.s    noalias1
  473.     move.w    d1,d0
  474.     subq.w    #1,d0        ; adjust for aliasdrv base
  475.     cmp.w    #$1f,d0        ; legal drive?
  476.     bhi.s    nobpb        ; no -- ignore it
  477. noalias1:
  478.     cmp.w    #$14,d0        ; drive U:?
  479.     beq.s    nochng        ; yes, no change
  480.     move.l    _old_mediach+8,a0    ; not our drive
  481.     jmp    (a0)        ; call the old vector for it
  482. nochng:
  483.     moveq.l    #0,d0        ; 0 means "definitely no change"
  484.     rts
  485.  
  486. _new_rwabs:
  487.     move.w    $e(sp),d0    ; check the drive
  488.     cmp.w    #$1f,d0        ; legal drive?
  489.     bhi.s    noalias2    ; no
  490.     move.w    d0,d1        ; get index
  491.     add.w    d0,d1        ; convert to index
  492.     lea    _aliasdrv,a0
  493.     move.w    0(a0,d1.w),d1    ; alias drive?
  494.     beq.s    noalias2
  495.     move.w    d1,d0
  496.     subq.w    #1,d0        ; adjust for aliasdrv base
  497.     cmp.w    #$1f,d0        ; legal drive?
  498.     bhi.s    nobpb        ; no -- ignore it
  499. noalias2:
  500.     cmp.w    #$14,d0        ; drive U:?
  501.     beq.s    rwdone        ; yes, fake it
  502.     move.l    _old_rwabs+8,a0    ; not our drive
  503.     jmp    (a0)        ; call the old vector for it
  504. rwdone:
  505.     moveq.l    #0,d0        ; 0 means "successful operation"
  506.     rts
  507.  
  508.     DATA
  509. ; buffer for faked mouse packet (actually only 3 bytes)
  510.  
  511. faked_packet:
  512.     dc.l    0
  513.  
  514. ; here we store the additional button state
  515. third_button:
  516.     dc.w    0
  517.  
  518.     END
  519.